import os
import sys
import json
import time
import codecs
import base64
import hashlib
import datetime
import requests
import operator
from urllib.parse import unquote, quote
from PyQt5.QtGui import QIcon, QFontMetrics, QPixmap
from PyQt5.QtCore import QStringListModel
from PyQt5.QtWidgets import (
    QWidget, QPushButton, QComboBox, QMessageBox, QListView, QCheckBox, QLabel,
    QTextEdit, QLineEdit, QFileDialog, QGridLayout, QApplication, QVBoxLayout,
    QHBoxLayout)

title = 'httpTool v1.2.6 2019-09-20 (w)'
w_main = None
w_har = None
w_img = None
pub = None

readme = '''
httptool工具箱
2019-04-18
water
'''


class Pub():
    def __init__(self):
        super().__init__()

    def find_str_between(self, l, s_s, s_e):
        if l.find(s_s) == -1:
            return ""
        i_s = l.find(s_s) + len(s_s)
        s = l[i_s:]
        if s_e != "":
            i_e = s.find(s_e)
            s = s[:i_e]
        return s

    # 获取当前日期和时间 0.普通格式; 1.带毫秒格式; 2.文件名可用格式
    def now(self, n=0):
        if n == 0:
            return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        elif n == 1:
            ct = time.time()
            local_time = time.localtime(ct)
            data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
            data_secs = (ct - int(ct)) * 1000
            time_stamp = "%s.%03d" % (data_head, data_secs)
            return time_stamp
        elif n == 2:
            return datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        else:
            return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # 获取当前日期字符串
    def now_date(self):
        return datetime.datetime.now().strftime("%Y-%m-%d")

    # 获取当前时间字符串 0.普通格式; 1.带毫秒格式; 2.文件名可用格式
    def now_time(self, n=0):
        if n == 0:
            return datetime.datetime.now().strftime("%H:%M:%S")
        elif n == 1:
            ct = time.time()
            local_time = time.localtime(ct)
            data_head = time.strftime("%H:%M:%S", local_time)
            data_secs = (ct - int(ct)) * 1000
            time_stamp = "%s.%03d" % (data_head, data_secs)
            return time_stamp
        elif n == 2:
            return datetime.datetime.now().strftime("%H-%M-%S")
        else:
            return datetime.datetime.now().strftime("%H:%M:%S")

    # curl to python script
    def curl2python(self, shell='', b_unquote=True, js=None):
        ls = []
        if shell != '':
            s = shell
            s = s.replace(' -H ', ' \n-H ')
            s = s.replace(' --compressed', ' \n--compressed')
            s = s.replace(' --data', ' \n--data')
            s = s.replace(' --data-binary', ' \n--data-binary')
            s = s.replace('"%"', '%')
            ls = s.split('\n')
        s = '''
# curl to python3 v1.1 
# 2018-09-09 water 
import requests
'''
        sh = ""
        sc = ""
        sd = ""
        ls_data = {}
        s_data = ''
        ls_header = {}
        ls_cookie = {}
        if shell != '':
            for l in ls:
                l = l.strip()
                if l == '':
                    continue
                if l[:3] == "-H ":
                    s1 = l[4:]
                    s1 = s1[:-1]
                    s1 = s1.strip()
                    r = s1.split(':')
                    s2 = s1.replace(r[0] + ':', '').strip()
                    if 'cookie' == r[0].lower():
                        ls2 = s2.split(';')
                        for l2 in ls2:
                            r2 = l2.split('=')
                            key = r2[0].strip()
                            if b_unquote:
                                key = unquote(key)
                            val = r2[1]
                            if b_unquote:
                                val = unquote(val)
                            ls_cookie[key] = val
                            print(key)
                            # if sc != '':
                            #    sc += ','
                            # sc += "\n\t'%s': '%s'" % (r2[0].strip(), r2[1])
                    else:
                        ls_header[r[0].strip()] = s2
                        # if sh != '':
                        #    sh += ','
                        # sh += "\n\t'%s': '%s'" % (r[0].strip(), s2)
                elif l[:7] == '--data ':
                    s1 = l[8:]
                    s1 = s1[:-1]
                    ls2 = s1.split('&')
                    for l2 in ls2:
                        r2 = l2.split('=')
                        if len(r2) < 2:
                            continue
                        key = r2[0].strip()
                        if b_unquote:
                            key = unquote(key)
                        val = r2[1]
                        if b_unquote:
                            val = unquote(val)
                        ls_data[key] = val

                elif l[:14] == '--data-binary ':
                    try:
                        s_data = l[14:]
                        # s_json = l[15:]
                        # s_json = s_json[:-1]
                        # js_data = json.loads(s_json)
                        # print(js_data)
                        # for key in js_data:
                        #     ls_data[key] = js_data[key]
                    except:
                        print('error! %s' % l[15:])
                    pass
                elif 'curl ' in l:
                    s += "url = %s\n" % l.replace('curl ', '')
                else:
                    # print(l)
                    # s += "\n%s" % l
                    pass
        else:
            s += "url = '%s'\n" % js['url']
            ls_data = js['data']
            ls_header = js['headers']
            ls_cookie = js['cookies']
            s_data = js['data_str']

        ls_header = sorted(ls_header.items(), key=operator.itemgetter(0))
        ls_header = dict(ls_header)

        ls_cookie = sorted(ls_cookie.items(), key=operator.itemgetter(0))
        ls_cookie = dict(ls_cookie)

        ls_data = sorted(ls_data.items(), key=operator.itemgetter(0))
        ls_data = dict(ls_data)

        # print(ls_header)
        for r, v in ls_header.items():
            if sh != '':
                sh += ','
            sh += "\n    '%s': '%s'" % (r, v)

        for r, v in ls_cookie.items():
            if sc != '':
                sc += ','
            sc += "\n    '%s': '%s'" % (r, v)

        for r, v in ls_data.items():
            if sd != '':
                sd += ','
            sd += "\n    '%s': '%s'" % (r, v)

        sh = "\nheaders = {%s\n}" % sh
        sc = "\ncookies = {%s\n}" % sc

        if len(ls_data) > 0:
            sd = "\ndata = {%s\n}" % sd
        if s_data != '':
            sd = "\ndata = %s" % s_data

        s += "%s" % sh
        s += "%s" % sc

        if len(ls_data) > 0 or s_data != '':
            s += "%s" % sd
        s += '''
con = requests.session()
con.headers.update(headers)
con.cookies.update(cookies)
'''

        if len(ls_data) > 0 or s_data:
            s += 'r = con.post(url, data)\n'
        else:
            s += 'r = con.get(url)\n'

        s += 's = r.text\n'
        s += 'print(s)'
        return s

    # url to python script
    def url2python(self, url, b_unquote=True):
        s = ""
        ls = url.split("?")
        if len(ls) == 1:
            s = "url='%s'" % url
            return s
        s = "url='%s'\n" % ls[0]
        rs = ls[1].split('&')
        s += 'data={\n'
        i1 = 0
        for l in rs:
            if i1 > 0:
                s += ",\n"
            r = l.split('=')
            key = r[0].strip()
            if b_unquote:
                key = unquote(key)
            val = r[1]
            if b_unquote:
                val = unquote(val)
            s += "\t'%s': '%s'" % (key, val)
            i1 += 1
        s += "\n}"
        return s

    def url2csharp(self, url):
        s = ""
        ls = url.split("?")
        if len(ls) == 1:
            s = 'string url="%s";' % url
            return s
        s = 'string url="%s";\n' % ls[0]
        rs = ls[1].split('&')
        s += 'var data = new Dictionary<String, object>{\n'
        i1 = 0
        for l in rs:
            if i1 > 0:
                s += ",\n"
            r = l.split('=')
            key = r[0].strip()
            key = unquote(key)
            val = r[1]
            val = unquote(val)
            s += '\t{ "%s", "%s" }' % (key, val)
            i1 += 1
        s += "\n};"
        return s

    # 有道翻译
    def dict_youdao(self, q):
        url = "http://fanyi.youdao.com/openapi.do"
        r = requests.post(url, {
            "keyfrom": "wp-cloud", "key": "1059734975",
            "type": "data", "doctype": "json", "version": "1.1",
            "q": q})
        s = r.text
        s_json = str(s)
        s_json = json.dumps(json.loads(s), indent=4, sort_keys=False, ensure_ascii=False)
        return s_json

        j = json.loads(s)
        # s_err = j["errorCode"]
        s = ""
        try:
            s_tra = j["translation"]
            for s1 in s_tra:
                s += s1 + ";"
            s += "\n"
        except:
            pass
        try:
            s_bas = j["basic"]["explains"]
            # s += "说明：\n"
            for s1 in s_bas:
                s += s1 + "\n"
        except:
            pass
        return s.strip()

    # 百度翻译
    def dict_baidu(self, q=""):
        appid = '20190125000259212'
        paswd = 'OFvF7gHEWuUGQctQ4R33'
        salt = int(round(time.time() * 1000))
        s = '%s%s%s%s' % (appid, q, salt, paswd)
        sign = '%s' % hashlib.md5(s.encode('utf-8')).hexdigest()
        url = 'https://fanyi-api.baidu.com/api/trans/vip/translate'
        r = requests.post(url, {
            "q": q,
            "from": "auto",
            "to": "auto",
            "appid": appid,
            "salt": salt,
            "sign": sign})
        s = r.text
        s = s.encode('utf-8').decode('unicode_escape')
        s_json = json.dumps(json.loads(s), indent=4, sort_keys=False, ensure_ascii=False)
        # print(s_json)
        return s_json

    # AI
    def ai(self, msg):
        key = "25f4de34cd2234bc95f5d182af63c303"
        data = {'key': key,
                'info': msg,
                'userid': '10544'}
        url = "http://www.tuling123.com/openapi/api"
        r = requests.post(url, data)
        s = r.text
        # print(page)
        # js = json.loads(page)
        # s = js["text"]
        s_json = json.dumps(json.loads(s), indent=4, sort_keys=False, ensure_ascii=False)
        return s_json

    runcode = ''

    def compile(self, language, code):
        try:
            print('%s\t%s\t%s' % (self.runcode, language, code))
            url = "https://m.runoob.com/api/compile.php"
            # r = requests.post(url, {"code": code, "language": t, "stdin": "", "fileext": "py3"})
            r = requests.post(url, {"code": code, "language": self.runcode})
            s = r.text
            # print(s)
            js = json.loads(s)
            s_out = js["output"]
            s_err = js["errors"]
            s_tim = ''
            if 'time' in js:
                s_tim = js["time"]
            # print("%s %s" % (s_tim, s_err))
            rs = ''
            if s_out != None:
                rs = s_out
            else:
                rs = 'null'
            if s_err.strip() != "":
                rs += 'errors: %s' % s_err
            if s_tim.strip() != "":
                rs += 'time: %s' % s_tim

            # if len(rs) > 1000:
            #    rs = rs[:1000] + "\n。。。"
            return rs
        except:
            return "error!"


class WHttpTool(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.cbox0 = QCheckBox('参数解码', self)
        # self.cbox0.toggle()
        self.cbox0.stateChanged.connect(self.cb1_click)

        self.tboxSrc = QTextEdit()
        self.tboxSrc.setMaximumHeight(150)
        self.metrics = QFontMetrics(self.tboxSrc.font())
        self.tboxSrc.setTabStopWidth(4 * self.metrics.width(' '))
        self.tboxSrc.dropEvent = self.dropEvent
        self.tboxOut = QTextEdit()

        self.btn01 = QPushButton("Curl2Python")
        self.btn02 = QPushButton("MD5")
        self.btn03 = QPushButton("日期转时间戳")
        self.btn04 = QPushButton("时间戳转日期")
        self.btn05 = QPushButton("Url2Src")
        self.btn06 = QPushButton("Url编码")
        self.btn07 = QPushButton("Url解码")
        self.btn08 = QPushButton("Unicode编码")
        self.btn09 = QPushButton("Unicode解码")
        self.btn10 = QPushButton("JSON Format")
        self.btn11 = QPushButton("有道翻译")
        self.btn12 = QPushButton("百度翻译")
        self.btn13 = QPushButton("AI")
        self.btn14 = QPushButton("Base64转Img")
        self.cbox1 = QComboBox()
        self.btn20 = QPushButton("运行")
        self.cbox2 = QComboBox()
        self.btn21 = QPushButton("转换")
        self.btn22 = QPushButton("Open .har")
        self.cbox1.addItem('PHP')
        self.cbox1.addItem('Python')
        self.cbox1.addItem('Python3')
        self.cbox1.addItem('Java')
        self.cbox1.addItem('C')
        self.cbox1.addItem('C++')
        self.cbox1.addItem('Ruby')
        self.cbox1.addItem('C#')
        self.cbox1.addItem('Scala')
        self.cbox1.addItem('Objective C')
        self.cbox1.addItem('Perl')
        self.cbox1.addItem('Bash')
        self.cbox1.addItem('VB.NET')
        self.cbox1.addItem('Swift')
        self.cbox1.addItem('Go')
        self.cbox1.addItem('Node.js')
        self.cbox1.addItem('Lua')
        self.cbox1.addItem('Pascal')
        self.cbox1.addItem('Kotlin')
        self.cbox2.addItem('\\ -> /')
        self.cbox2.addItem('\\ -> \\\\')
        self.cbox2.addItem('/ -> \\')
        self.cbox2.addItem('url -> python')

        self.btn01.clicked.connect(self.btn1Clicked)
        self.btn02.clicked.connect(self.btn2Clicked)
        self.btn03.clicked.connect(self.btn3Clicked)
        self.btn04.clicked.connect(self.btn4Clicked)
        self.btn05.clicked.connect(self.btn5Clicked)
        self.btn06.clicked.connect(self.btn6Clicked)
        self.btn07.clicked.connect(self.btn7Clicked)
        self.btn08.clicked.connect(self.btn8Clicked)
        self.btn09.clicked.connect(self.btn9Clicked)
        self.btn10.clicked.connect(self.btn10Clicked)
        self.btn11.clicked.connect(self.btn11Clicked)
        self.btn12.clicked.connect(self.btn12Clicked)
        self.btn13.clicked.connect(self.btn13Clicked)
        self.btn14.clicked.connect(self.btn14Clicked)
        self.cbox1.currentIndexChanged.connect(self.cbox1Change)
        self.btn20.clicked.connect(self.btn20Clicked)
        self.cbox2.currentIndexChanged.connect(self.cbox2Change)
        self.btn21.clicked.connect(self.btn21Clicked)
        self.btn22.clicked.connect(self.btn22Clicked)

        grid = QGridLayout()
        grid.setSpacing(10)

        grid.addWidget(self.tboxSrc, 1, 0, 1, 8)

        grid.addWidget(self.cbox0, 2, 0)
        grid.addWidget(self.btn01, 2, 1)
        grid.addWidget(self.btn22, 2, 2)
        grid.addWidget(self.btn02, 2, 3)
        grid.addWidget(self.btn03, 2, 4)
        grid.addWidget(self.btn04, 2, 5)
        grid.addWidget(self.btn05, 2, 6)
        grid.addWidget(self.btn14, 2, 7)

        grid.addWidget(self.btn06, 3, 0)
        grid.addWidget(self.btn07, 3, 1)
        grid.addWidget(self.btn08, 3, 2)
        grid.addWidget(self.btn09, 3, 3)
        grid.addWidget(self.btn10, 3, 4)
        grid.addWidget(self.btn11, 3, 5)
        grid.addWidget(self.btn12, 3, 6)
        grid.addWidget(self.btn13, 3, 7)

        grid.addWidget(self.cbox1, 4, 0)
        grid.addWidget(self.btn20, 4, 1)
        grid.addWidget(self.cbox2, 4, 2)
        grid.addWidget(self.btn21, 4, 3)

        # grid.addWidget(self.labText, 4, 0)
        grid.addWidget(self.tboxOut, 5, 0, 1, 8)

        self.setAcceptDrops(True)
        self.setLayout(grid)
        self.setGeometry(100, 100, 900, 500)
        self.setWindowTitle(title)
        self.setWindowIcon(QIcon('water.ico'))
        self.show()

        if os.path.exists("his.txt"):
            f = codecs.open("his.txt")
            s = f.read()
            f.close()
            self.tboxSrc.setPlainText(s)
        # '''

    def dropEvent(self, QDropEvent):
        # Linux
        # txt_path = QDropEvent.mimeData().text().replace('file:///', '/').strip()

        # Windows
        # txt_path = QDropEvent.mimeData().text().replace('file:///', '')

        fn = QDropEvent.mimeData().text()
        fn = fn.replace('file:///', '')
        print(fn)

        ext = os.path.splitext(fn)[1].lower()
        if ext == '.har':
            self.open_har(fn)
        elif ext in ['.jpg', '.png', '.gif', 'jpeg']:
            self.open_img(fn)
            f = open(fn, 'rb')
            s = base64.b64encode(f.read())
            f.close()
            s = s.decode()
            print(s)
            s = 'data:image/%s;base64,%s' % (ext[1:], s)
            self.tboxSrc.setPlainText(fn)
            self.tboxOut.setPlainText(s)

    def cb1_click(self):
        pass

    def btn1Clicked(self):
        code = self.tboxSrc.toPlainText()
        chk1 = self.cbox0.isChecked()
        txt = ""
        try:
            if code[:4].lower() == 'curl':
                txt = pub.curl2python(shell=code, b_unquote=chk1)
            if code[:4].lower() == 'http':
                txt = pub.url2python(code)
        except:
            txt = '生成代码出错！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # MD5
    def btn2Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            txt = hashlib.md5(code.encode('utf-8')).hexdigest()
        except:
            txt = '计算MD5出错！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # 时间转日期
    def btn3Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            if code == '':
                f = '%Y-%m-%d %H:%M:%S'
                s_d = datetime.datetime.now().strftime(f)
                txt = '%s\n%d' % (s_d, int(round(time.time() * 1000)))
            else:
                f = '%Y-%m-%d %H:%M:%S'
                if len(code) == 19:
                    f = '%Y-%m-%d %H:%M:%S'
                elif len(code) == 16:
                    f = '%Y-%m-%d %H:%M'
                elif len(code) == 13:
                    f = '%Y-%m-%d %H'
                elif len(code) == 10:
                    f = '%Y-%m-%d'
                dt = datetime.datetime.strptime(code, f)
                txt = '%d' % time.mktime(dt.timetuple())
        except:
            txt = '日期数据无效！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # 时间转日期
    def btn4Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            s_dt = code
            if len(s_dt) > 11:
                s_dt = s_dt[:-3]
            f = '%Y-%m-%d %H:%M:%S'
            txt = datetime.datetime.fromtimestamp(int(s_dt)).strftime(f)
        except:
            txt = '时间戳数据无效！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # Url2Src
    def btn5Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            txt = requests.get(code).text
        except:
            txt = '获取数据出错！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # Url编码
    def btn6Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            txt = quote(code)
        except:
            txt = "编码错误!"
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # Url解码
    def btn7Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            txt = unquote(code)
        except:
            txt = "解码错误!"
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # Unicode编码
    def btn8Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            txt = code.encode('unicode_escape').decode('utf-8')
        except:
            txt = '编码错误!'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # Unicode解码
    def btn9Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            txt = code.encode('utf-8').decode('unicode_escape')
        except:
            txt = '解码错误! (字符串不是unicode编码)'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # 格式化JSON
    def btn10Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            txt = json.dumps(json.loads(code), sort_keys=False, indent=4, ensure_ascii=False)
        except:
            txt = '格式化JSON出错！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # 有道翻译
    def btn11Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            txt = pub.dict_youdao(code)
        except:
            txt = '查询出错！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # 百度翻译
    def btn12Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            txt = pub.dict_baidu(code)
        except:
            txt = '查询出错！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # AI
    def btn13Clicked(self):
        code = self.tboxSrc.toPlainText()
        txt = ""
        try:
            txt = pub.ai(code)
        except:
            txt = '查询出错！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # base64转图片
    def btn14Clicked(self):
        code = self.tboxSrc.toPlainText()
        if ',' in code:
            code = code.split(',')[1]
        txt = ""
        try:
            d = '%s\\Pictures\\temp' % os.path.expanduser('~')
            # print(d)
            if not os.path.exists(d):
                os.makedirs(d)
            fn = '%s\\%s' % (d, pub.now(2))
            b = base64.b64decode(code.encode())
            s = str(b[:10])
            if 'PNG' in s:
                fn += '.png'
            elif 'GIF' in s:
                fn += '.gif'
            elif 'JFIF' in s:
                fn += '.jpg'
            else:
                fn += '.jpg'
            print(fn)
            f = open(fn, 'wb')
            f.write(b)
            f.close()
            txt = fn
            w_img.showImg(fn)
        except:
            txt = '转换出错！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # select language
    def cbox1Change(self):
        self.tboxOut.setPlainText('')
        language = self.cbox1.currentText()
        s_type = '''2960.Kotlin,73.Pascal,66.Lua,22.Node.js,21.Go,20.Swift,19.VB.NET,18.Bash,17.Perl,
        16.Objective C,15.Scala,14.C#,13.Ruby,12.C++,11.C,10.Java,9.Python3,6.Python,1.PHP'''

        t = ''
        ls = s_type.split(',')
        ls = [l.strip() for l in ls]
        for l in ls:
            if language in l:
                t = l.split('.')[0]
                break
        if t == "":
            code = "error language"
            self.tboxSrc.setPlainText(code)
            return

        # global runcode
        url = 'https://c.runoob.com/compile/%s' % t
        r = requests.get(url)
        s = r.text
        code = pub.find_str_between(s, '<textarea class="form-control"  id="code" name="code" rows="18">',
                                    '</textarea>')
        pub.runcode = pub.find_str_between(s, 'runcode = ', ';')
        self.tboxSrc.setPlainText(code)

    # run script
    def btn20Clicked(self):
        code = self.tboxSrc.toPlainText()
        language = self.cbox1.currentText()
        txt = ""
        try:
            txt = pub.compile(language, code)
        except:
            txt = '查询出错！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # \ -> /
    def cbox2Change(self):
        self.btn21Clicked()

    # replace
    def btn21Clicked(self):
        code = self.tboxSrc.toPlainText()
        i = self.cbox2.currentIndex()
        txt = code
        try:
            if i == 0:
                txt = txt.replace('\\', '/')
            elif i == 1:
                txt = txt.replace('\\', '\\\\')
            elif i == 2:
                txt = txt.replace('/', '\\')
            elif i == 3:
                txt = txt.replace('?', '"\nurl += "?')
                txt = txt.replace('&', '"\nurl += "&')
                txt = 'url = "%s"' % txt
        except:
            txt = '转换出错！'
        txt = txt.replace("\t", "    ")
        self.tboxOut.setPlainText(txt)

    # open .har
    def btn22Clicked(self):

        fname = QFileDialog.getOpenFileName(self, 'Open file', '.', '*.har')

        if not fname[0]:
            return

        self.open_har(fname[0])

    def open_har(self, fn):
        self.fn_har = fn
        print(self.fn_har)
        f = codecs.open(self.fn_har, 'r', 'utf-8')
        s = f.read()
        f.close()
        # print(s)

        w_har.fillItem(self.fn_har)

        self.tboxSrc.setPlainText(s)

    def har2python(self, index):
        f = codecs.open(self.fn_har, 'r', 'utf-8')
        s = f.read()
        f.close()
        js = json.loads(s)
        rq = js['log']['entries'][index]['request']
        url = rq['url']
        data = rq['queryString']
        postdata = rq['postData']
        headers = rq['headers']
        cookies = rq['cookies']
        ls_data = {}
        ls_headers = {}
        ls_cookies = {}
        s_data = ''
        chk1 = self.cbox0.isChecked()
        for r in headers:
            # print(r)
            n = r['name']
            v = r['value']
            if n.lower() == 'cookie':
                continue
            ls_headers[n] = v
        for r in cookies:
            # print(r)
            n = r['name']
            v = r['value']
            if chk1:
                v = unquote(v)
            else:
                v = quote(v)
            ls_cookies[n] = v
        for r in data:
            # print(r)
            n = r['name']
            v = r['value']
            ls_data[n] = v
        if 'text' in postdata:
            s_data = "'%s'" % postdata['text']
        js = {
            'url': url,
            'data': ls_data,
            'data_str': s_data,
            'headers': ls_headers,
            'cookies': ls_cookies
        }
        # print(js)
        s = pub.curl2python(js=js, b_unquote=chk1)
        self.tboxSrc.setPlainText(json.dumps(rq, sort_keys=False, indent=4, ensure_ascii=False))
        self.tboxOut.setPlainText(s)

    # open img
    def open_img(self, fn):
        self.fn_img = fn
        w_img.showImg(self.fn_img)


class WHarList(QWidget):
    line_len = 150
    # slm = None
    # listview = None
    ls_index = []

    def __init__(self, parent=None):
        super(WHarList, self).__init__(parent)
        self.setAcceptDrops(True)
        # 设置初始大小与标题
        self.resize(900, 500)
        self.setWindowTitle('network')
        self.setWindowIcon(QIcon('water.ico'))

        self.lab1 = QLabel()
        self.lab1.setText('Filter')
        self.tbox1 = QLineEdit()
        self.tbox1.textChanged.connect(self.tbox1_change)

        # 垂直布局
        # layout = QVBoxLayout()

        # 实例化列表视图
        self.listview = QListView()
        # self.dropEvent = self.dropEvent

        # 实例化列表模型，添加数据
        self.slm = QStringListModel()
        # self.qList = ['Item 1', 'Item 2', 'Item 3', 'Item 4']

        # 设置模型列表视图，加载数据列表
        # self.slm.setStringList(self.qList)

        # 设置列表视图的模型
        # self.listview.setModel(self.slm)

        # 单击触发自定义的槽函数
        # self.listview.clicked.connect(self.clicked)

        grid = QGridLayout()
        grid.setSpacing(10)
        grid.addWidget(self.lab1, 1, 0)
        grid.addWidget(self.tbox1, 1, 1, 1, 7)
        grid.addWidget(self.listview, 2, 0, 1, 8)
        self.setLayout(grid)

        # 设置窗口布局，加载控件
        # layout.addWidget(self.listview)
        # self.setLayout(layout)

    # def dropEvent(self, QDropEvent):
    #
    #     # Linux
    #     # txt_path = QDropEvent.mimeData().text().replace('file:///', '/').strip()
    #
    #     # Windows
    #     # txt_path = QDropEvent.mimeData().text().replace('file:///', '')
    #
    #     fn = QDropEvent.mimeData().text()
    #     fn = fn.replace('file:///', '')
    #     print(fn)
    #     ext = os.path.splitext(fn)[1].lower()
    #     if ext == '.har':
    #         self.fillItem(fn)

    def fillItem(self, fn):
        self.fn = fn
        f = codecs.open(fn, 'r', 'utf-8')
        s = f.read()
        f.close()

        js = json.loads(s)
        ls = []
        self.ls_index = []
        i = -1
        for r in js['log']['entries']:
            i += 1
            self.ls_index.append(i)
            url = r['request']['url']
            method = r['request']['method']
            if len(url) > self.line_len:
                s1 = url[:self.line_len - 5]
                s2 = url[-5:]
                url = '%s...%s' % (s1, s2)
            s3 = '%03d [%03d] %-6s %s' % (i + 1, i, method, url)
            # print(s3)
            ls.append(s3)

        self.qList = ls
        # 设置模型列表视图，加载数据列表
        self.slm.setStringList(self.qList)

        # 设置列表视图的模型
        self.listview.setModel(self.slm)

        # 单击触发自定义的槽函数
        self.listview.clicked.connect(self.ls_clicked)
        self.show()

    def ls_clicked(self, qModelIndex):
        # 提示信息弹窗，你选择的信息
        s = self.qList[qModelIndex.row()]
        print(s)
        # QMessageBox.information(self, 'ListWidget', s)
        s1 = s.split('[')[1].split(']')[0]
        print(s1)
        i = int(s1)
        print('index: %s' % i)
        w_main.har2python(i)

    def tbox1_change(self, t):
        print(t)
        ls_filter = t.split(';')

        f = codecs.open(self.fn, 'r', 'utf-8')
        s = f.read()
        f.close()

        js = json.loads(s)
        ls = []
        self.ls_index = []
        i = -1
        i1 = 0
        for r in js['log']['entries']:
            i += 1
            self.ls_index.append(i)
            url = r['request']['url']
            method = r['request']['method']
            ls_f = []
            ls_unf = []
            for r2 in ls_filter:
                r2 = r2.strip()
                if r2[:1] == '!':
                    s0 = r2[1:]
                    if s0 != '':
                        ls_unf.append(s0)
                elif r2 != '':
                    ls_f.append(r2)

            if len(ls_unf) > 0:
                b_c = False
                for l in ls_unf:
                    if l in url:
                        b_c = True
                        break
                if b_c:
                    continue

            if len(ls_f) > 0:
                b_c = True
                for l in ls_f:
                    if l in url:
                        b_c = False
                        break
                if b_c:
                    continue

            if len(url) > self.line_len:
                s1 = url[:self.line_len - 5]
                s2 = url[-5:]
                url = '%s...%s' % (s1, s2)
            i1 += 1
            s3 = '%03d [%03d] %-6s %s' % (i1, i, method, url)
            # print(s3)
            ls.append(s3)

        self.qList = ls
        # 设置模型列表视图，加载数据列表
        self.slm.setStringList(self.qList)

        # 设置列表视图的模型
        self.listview.setModel(self.slm)


class WImg(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.hbox = QHBoxLayout(self)
        # self.pixmap = QPixmap()

        self.lbl = QLabel(self)
        # self.lbl.setPixmap(self.pixmap)

        self.hbox.addWidget(self.lbl)
        self.setLayout(self.hbox)

        # self.dropEvent = self.dropEvent

        # self.move(300, 200)
        self.setWindowTitle('img')
        # self.show()

    # def dropEvent(self, QDropEvent):
    #     # Linux
    #     # txt_path = QDropEvent.mimeData().text().replace('file:///', '/').strip()
    #
    #     # Windows
    #     # txt_path = QDropEvent.mimeData().text().replace('file:///', '')
    #
    #     fn = QDropEvent.mimeData().text()
    #     fn = fn.replace('file:///', '')
    #     print(fn)
    #     ext = os.path.splitext(fn)[1].lower()
    #     if ext == ['.jpg', '.png', '.gif', 'jpeg']:
    #         self.showImg(fn)

    def showImg(self, fn):
        self.resize(200, 100)
        # self.hbox = QHBoxLayout(self)
        self.pixmap = QPixmap(fn)

        # self.lbl = QLabel(self)
        self.lbl.setPixmap(self.pixmap)

        # self.hbox.addWidget(self.lbl)
        # self.setLayout(self.hbox)

        # self.move(300, 200)
        self.setWindowTitle(fn)
        self.show()


if __name__ == '__main__':
    # fn = 'his.txt'
    # f = open(fn, 'r')
    # s = f.read()
    # f.close()
    # s2 = curl2python(s)
    # print(s2)
    # exit()

    # fn = 'C:/Users/wp0544/Downloads/Archive 18-12-02 20-35-37.har'
    # f = codecs.open(fn, 'r', 'utf-8')
    # s = f.read()
    # f.close()
    #
    # js = json.loads(s)
    # ls = []
    # for r in js['log']['entries']:
    #     url = r['request']['url']
    #     method = r['request']['method']
    #     if len(url) > 50:
    #         s1 = url[:45]
    #         s2 = url[-5:]
    #         url = '%s...%s' % (s1, s2)
    #     print('%s\t%s' % (method, url))
    #     ls.append(url)
    # exit()

    # data = {
    #     'url': 'http://xxx.xxx.xxx',
    #     'data': {},
    #     'headers': {
    #         'Host': 'qidian.gtimg.com',
    #         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:63.0) Gecko/20100101 Firefox/63.0',
    #         'Accept': 'text/css,*/*;q=0.1',
    #         'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    #         'Accept-Encoding': 'gzip, deflate, br',
    #         'Referer': 'https://www.qidian.com/',
    #         'Connection': 'keep-alive'
    #     },
    #     'cookies': {
    #         'Host': 'qidian.gtimg.com',
    #         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:63.0) Gecko/20100101 Firefox/63.0',
    #         'Accept': 'text/css,*/*;q=0.1',
    #         'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    #         'Accept-Encoding': 'gzip, deflate, br',
    #         'Referer': 'https://www.qidian.com/',
    #         'Connection': 'keep-alive'
    #     }
    # }
    # s = curl2python(js=data)
    # print(s)
    # exit()
    pub = Pub()
    app = QApplication(sys.argv)
    w_main = WHttpTool()
    w_har = WHarList()
    w_img = WImg()
    sys.exit(app.exec_())
